import PluginsLoader from "../../lib/plugins/loader.js"
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { exec, execSync } = require("child_process");
import fetch from "node-fetch";
import fs from 'fs'

let plugins_list_url = `https://gitee.com/qiannqq/yunzai-plugin-JS/raw/master/html/plugins-list.json`
let pluginsList_temp

let status = { }

/**
 * 作者：千奈千祁(2632139786)
 * Gitee主页：Gitee.com/QianNQQ
 * Github主页：Github.com/QianNQQ
 * 
 * 该插件所有版本发布于 该仓库(https://gitee.com/qiannqq/yunzai-plugin-JS)
 * 本插件及该仓库的所有插件均遵循 GPL3.0 开源协议
 * 
 * 请勿使用本插件进行盈利等商业活动行为
 */

export class example2 extends plugin {
    constructor () {
      super({
        name: '插件管理器',
        dsc: '插件管理器@千奈千祁',
        event: 'message',
        priority: -1,
        rule: [
          {
            reg: '^#插件(列表|市场|大全)$',
            fnc: '插件列表'
          },{
            reg: '^#安装插件(.*)$',
            fnc: '安装插件'
          },{
            reg: '^#(删除|卸载)插件(.*)$',
            fnc: '卸载插件'
          },{
            reg: '^#已安装插件(列表)?$',
            fnc: '已安装插件'
          },{
            reg: '^#搜索插件(.+)$',
            fnc: '搜索插件'
          },{
            reg: /^#安装JS插件.+$/i,
            fnc: '安装JS插件'
          },{
            reg: /^#(删除|卸载)js插件.+$/i,
            fnc: '卸载JS插件'
          },{
            reg: '^#(启用|开启|停用|禁用)插件.+$',
            fnc: 'modifyPluginStatus'
          },{
            reg: '^#(刷新|重载|载入)插件$',
            fnc: 'loadPlugin'
          },{
            reg: /^#更新(js)?插件.+$/i,
            fnc: 'updatePlugin'
          }
        ]
      })
    }
    async updatePlugin(e) {
      if(!e.isMaster) return false
      let commsg = e.msg.match(/^#更新(js)?插件(.*)$/i)
      if(status[commsg[2]]) {
        return await e.reply(`[${commsg[2]}]该插件正在更新中，请勿频繁操作`)
      }
      if(/^#更新js插件.+$/i.test(e.msg)) {
        if(!fs.existsSync(`./plugins/example/${commsg[2]}.js`)) {
          return await e.reply(`[${commsg[2]}]未找到该插件`)
        }
        let url = (await lplm(await this.getplugins(), { type: 'JS', name: commsg[2] })).url
        if(url === '未知') return await e.reply(`[${commsg[2]}]未找到该插件的源文件链接`)
        let result
        try {
          result = await (await fetch(url)).text()
        } catch (error) {
          logger.error(`[${commsg[2]}]插件更新下载失败`, error)
          return await e.reply(`[${commsg[2]}]插件更新下载失败`)
        }
        if(result !== '404: Not Found' && !/^\[session.*\]/.test(result)) { 
          await e.reply(`[${commsg[2]}]插件更新下载成功，正在安装中`)
          fs.writeFileSync('./plugins/example/' + commsg[2] + '.js', result, 'utf-8')
          await e.reply(`[${commsg[2]}]插件更新安装成功`)
          return true
        } else {
          return await e.reply(`[${commsg[2]}]插件安装更新失败，远程文件不存在`)
        }
      }
    }
    async loadPlugin(e) {
      if(!e.isMaster) return false
      await e.reply(`正在载入新插件`)
      await PluginsLoader.load(true)
      return await e.reply(`载入插件完成`)
    }
    async modifyPluginStatus(e) {
      if(!e.isMaster) return false
      let commsg = e.msg.match(/^#(启用|开启|停用|禁用)插件(.*)$/)
      let pluginPath = `./plugins/${commsg[2]}`
      let setStatus = { }
      if(commsg[1] == '启用' || commsg[1] == '开启') {
        setStatus.index = 'index.deactivate'
        setStatus.status = 'index.js'
        setStatus.aReply = '已经启用了'
        setStatus.bReply = '启用'
      } else {
        setStatus.index = 'index.js'
        setStatus.status = 'index.deactivate'
        setStatus.aReply = '已经禁用了'
        setStatus.bReply = '停用'
      }
      if (!fs.existsSync(`${pluginPath}/${setStatus.index}`)) {
        await e.reply(`[${commsg[2]}]该插件${fs.existsSync(`${pluginPath}/${setStatus.index}`) ? setStatus.aReply : "不存在"}`)
        return true
      }
      try {
        fs.renameSync(`${pluginPath}/${setStatus.index}`, `${pluginPath}/${setStatus.status}`)
        return await e.reply(`[${commsg[2]}]插件${setStatus.bReply}成功，重启后生效`)
      } catch (error) {
        logger.error(`[${commsg[2]}]插件${setStatus.bReply}失败`, error)
        return await e.reply(`[${commsg[2]}]插件${setStatus.bReply}失败\n${error.message}`)
      }

    }
    async 卸载JS插件(e) {
      if(!e.isMaster) return false
      let JsName = e.msg.match(/^#(删除|卸载)js插件(.*)$/i)[2]
      if(!JsName) return false

      if(!fs.existsSync(`./plugins/example/${JsName}.js`)) {
        await e.reply(`[${JsName}]该JS插件未安装`)
        return true
      }

      try {
        fs.unlinkSync(`./plugins/example/${JsName}.js`)
        await e.reply(`[${JsName}]插件卸载成功`)
      } catch (error) {
        await e.reply(`[${JsName}]插件卸载失败`)
        logger.error(`[${JsName}]插件卸载失败`, error)
      }
      return true
    }
    async 安装JS插件(e) {
      if(!e.isMaster) return false
      let JsName = e.msg.match(/^#安装js插件(.*)$/i)[1]
      if(!JsName) return false
      if(status[JsName]) {
        await e.reply(`[${JsName}]该插件正在安装中，请勿频繁操作`)
        return true
      }

      if(fs.existsSync(`./plugins/example/${JsName}.js`)) {
        await e.reply(`[${JsName}]该JS插件已经安装了`)
        return true
      }

      let plugins_list = await this.getplugins()
      let plugin_onoff = []

      for(let item of plugins_list) {
        if(item.pathname == JsName && item.type === 'JS') {
          plugin_onoff.push(item)
        }
      }

      if(plugin_onoff.length == 0) {
        await e.reply(`[${JsName}]插件不存在！`)
        return true
      }
      status[JsName] = true
      await e.reply(`[${JsName}]已搜索到插件，正在安装中...`)

      let JsContent
      try {
        JsContent = await (await fetch(plugin_onoff[0].url)).text()
        fs.writeFileSync('./plugins/example/' + JsName + '.js', JsContent, 'utf-8')
        await e.reply(`[${JsName}]插件安装成功`)
        status[JsName] = false
        return true
      } catch (error) {
        await e.reply(`[${JsName}]插件下载失败`)
        logger.error(`[${JsName}]插件下载失败`, error)
        status[JsName] = false
        return true
      }
    }
    async getplugins() {
      let timestamp = Math.floor(Date.now() / 1000);
      if(!pluginsList_temp?.time || pluginsList_temp.time+3600 <= timestamp) {
        pluginsList_temp = await fetch(plugins_list_url)
        pluginsList_temp = await pluginsList_temp.json()
        // pluginsList_temp = pluginsList_temp.filter(item => item.type !== 'JS')
        pluginsList_temp.time = timestamp
      }
      return pluginsList_temp
    }
    async 搜索插件(e) {
      if(!e.isMaster) return false
      let commsg = e.msg.match(/^#搜索插件(.*)$/)
      if(!commsg) return false

      let plugins_list = await this.getplugins()

      let pluginList = []
      for (let item of plugins_list) {
        for (let item2 in item) {
          if (item[item2].includes(commsg[1])) {
            pluginList.push(item);
            break; // 仅退出内层循环
          }
        }
      }
      if(pluginList.length == 0) {
        await e.reply(`未搜索到插件！`)
        return true
      }
      let msgList = []
      msgList.push({
        user_id: Bot.uin,
        message: `搜索到${pluginList.length}个插件`,
        nickname: Bot.nickname
      })
      for(let item of pluginList) {
        let msgList_ = 
`插件名称:${item.pluginname || item.pathname}
作者:${item.author}
简介:${item.describe}
插件链接:${item.url}
安装指令:#安装${item.type === "JS" ? item.type : ''}插件${item.pathname}`
        msgList.push({
          user_id: Bot.uin,
          message: msgList_,
          nickname: Bot.nickname
        })
      }
      if(e.isGroup) e.reply(await e.group.makeForwardMsg(msgList))
        else e.reply(await e.friend.makeForwardMsg(msgList))
    }
    async 已安装插件(e) {
      if(!e.isMaster) return false
      let files
      let jslist
      try {
        files = fs.readdirSync(`./plugins`, { withFileTypes: true });
        jslist = fs.readdirSync(`./plugins/example`)
      } catch(err) {
        await e.reply(`获取PathName时出错！\n${err.message}`)
        return true
      }
      jslist = jslist.filter(item => /.*\.js$/gi.test(item)).map(item => item.replace(/\.js$/gi, ''))
      let directories = files.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name);
      let local_plugins_list = []
      for (let item of directories) {
        if(item !== `example` && item !== `genshin` && item !== `system` && item !== `other` && item !== `adapter` && (fs.existsSync(`./plugins/${item}/index.js`) || fs.existsSync(`./plugins/${item}/index.deactivate`))) { 
          local_plugins_list.push(item)
        }
      }
      let n = local_plugins_list
      local_plugins_list = []
      for (let item of n) {
        // local_plugins_list = local_plugins_list.concat(jslist)
        let pluginStatus = false
        if(fs.existsSync(`./plugins/${item}/index.js`)) {
          pluginStatus = true
        }
        local_plugins_list.push( { 
          type: 'function',
          name: item,
          status: pluginStatus
         } )
      }
      for (let item of jslist) {
        local_plugins_list.push( { 
          type: 'JS',
          name: item,
          status: true
         } )
      }
      let cloud_plugins_list = await this.getplugins()
      let local_plugins_list_msg = []
      for (let litem of local_plugins_list) {
        local_plugins_list_msg.push(await lplm(cloud_plugins_list, litem))
      }
      let msgList = { 推荐: [], 功能性插件: [], 游戏插件: [], JS: [], 文游插件: [], 未知插件: [] }
      for (let item of local_plugins_list_msg) {
        let statusMsg
        if(item.type !== 'JS') {
          statusMsg = `\n${item.status ? '禁用' : '启用'}指令:#${item.status ? '禁用' : '启用'}插件${item.pathname}`
        }
        try {
          msgList[item.type].push({
            nickname: Bot.nickname,
            user_id: Bot.uin,
            message: `【当前插件状态:${item.status ? '✅启用' : '🚫禁用'}】\n插件名称:${item.pluginname || item.pathname}\n作者:${item.author}\n简介:${item.describe}\n插件链接:${item.url}\n卸载指令:#卸载${item.type === "JS" ? item.type : ''}插件${item.pathname}${statusMsg || ''}`
          })
        } catch { }
      }

      let msg = [
        {
          nickname: e.bot.nickname,
          user_id: e.bot.uin,
          message: `以下是所有已安装的插件`
        }
      ]

      for (let item in msgList) {
        if(msgList[item].length == 0) {
          delete msgList[item]
          continue
        }
        msgList[item] = await e.bot.pickUser(e.bot.uin).makeForwardMsg(msgList[item])
        try {
          let detail = msgList[item].data?.meta?.detail
          detail.news = [{ text: item }]
        } catch { }
        msg.push({
          nickname: e.bot.nickname,
          user_id: e.bot.uin,
          message: msgList[item]
        })
      }

      await e.reply(await e.bot.pickUser(e.bot.uin).makeForwardMsg(msg))
      return true
    }
    async 卸载插件(e) {
        if(!e.isMaster) return false
        let plugin_pathname = e.msg.match(/^#(删除|卸载)插件(.*)$/)[2]
        if(!plugin_pathname) {
          await e.reply(`要卸载的插件名为空！`)
          return true
        }
        if(!fs.existsSync(`./plugins/${plugin_pathname}`)) {
          await e.reply(`要卸载的插件不存在！`)
          return true
        }
        if(plugin_pathname == `miao-plugin` || plugin_pathname == `genshin` || plugin_pathname == `system` || plugin_pathname == `example` || plugin_pathname == `other`) {
          await e.reply(`系统组件不支持卸载`)
          return true
        }
        try {
          fs.rmSync(`./plugins/${plugin_pathname}`, { recursive: true, force: true })
        } catch(err) {
          await e.reply(`插件卸载失败！\n${err.message}`)
          return true
        }
        await e.reply(`插件卸载成功！`)
        return true
    }
    async 安装插件(e){
        if(!e.isMaster) return false
        let commsg = e.msg.match(/^#安装插件(.*)$/)
        let plugin_name = commsg[1]
        if(fs.existsSync(`./plugins/${plugin_name}`)) {
          await e.reply(`[${plugin_name}]该插件已经安装了`)
          return true
        }
        let plugins_list = await this.getplugins()
        let plugin_onoff = []
        for(let item of plugins_list) {
            if(item.pathname == plugin_name&& item.type !== 'JS') {
                plugin_onoff.push(item)
            }
        }
        if(plugin_onoff.length == 0) {
            await e.reply(`[${plugin_name}]插件不存在！`)
            return true
        }
        await e.reply(`[${plugin_onoff[0].pluginname}]已搜索到插件，正在安装中……`)
        let com
        if(plugin_onoff[0].url.includes(`github`)) {
            com = `git clone --depth=1 https://ghp.ci/${plugin_onoff[0].url} ./plugins/${plugin_onoff[0].pathname}/`
        } else {
            com = `git clone --depth=1 ${plugin_onoff[0].url}.git ./plugins/${plugin_onoff[0].pathname}/`
        }
        let com_result = await this.execSyncc(com, { encoding: 'buffer' })
        if(com_result.error) {
            await e.reply(`安装时出现错误！\n${com_result.error.message}`)
            return true
        }
        await e.reply(`[${plugin_onoff[0].pluginname}]插件下载完成！正在安装依赖……`)
        com = `cd ./plugins/${plugin_onoff[0].pathname}&& pnpm i --registry=https://registry.npmmirror.com`
        com_result = await this.execSyncc(com, { encoding: 'buffer' })
        if(com_result.error) {
            await e.reply(`[${plugin_onoff[0].pluginname}]安装依赖时出现错误！\n${com_result.stdout}`)
            console.log(com_result)
        }
        await e.reply(`[${plugin_onoff[0].pluginname}]插件安装成功！重启后生效`)
    }
    async 插件列表(e){
        if(!e.isMaster) return false
        let plugins_list = await this.getplugins()

        let msgList = { 推荐: [], 功能性插件: [], 游戏插件: [], 文游插件: [], JS: [] }
            
        for(let item of plugins_list) {
          try {
            msgList[item.type].push({
              nickname: Bot.nickname,
              user_id: Bot.uin,
              message: `插件名称:${item.pluginname || item.pathname}\n作者:${item.author}\n简介:${item.describe}\n插件链接:${item.url}\n安装指令:#安装${item.type === "JS" ? item.type : ''}插件${item.pathname}`
            })
          } catch { }
        }

        let msg = [
          {
            nickname: e.bot.nickname,
            user_id: e.bot.uin,
            message: `以下所有插件信息均来自Yunzai-Bot-plugins-index\n插件库地址：https://gitee.com/yhArcadia/Yunzai-Bot-plugins-index`
          }
        ]

        for (let item in msgList) {
          if(msgList[item].length == 0) {
            delete msgList[item]
            continue
          }
          msgList[item] = await e.bot.pickUser(e.bot.uin).makeForwardMsg(msgList[item])
          try {
            let detail = msgList[item].data?.meta?.detail
            detail.news = [{ text: item }]
          } catch { }
          msg.push({
            nickname: e.bot.nickname,
            user_id: e.bot.uin,
            message: msgList[item]
          })
        }

        await e.reply(await e.bot.pickUser(e.bot.uin).makeForwardMsg(msg))
        return true;
    }
    async execSyncc(cmd) {
      return new Promise((resolve, reject) => {
        exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
          resolve({ error, stdout, stderr });
        });
      });
    }
}

async function lplm(c, l) {
  let a;
  for (let item of c) {
    if(item.pathname == l.name) {
      a = item
      a.status = l.status
    }
  }
  if(!a) {
    a = {
      status: l.status,
      type: l.type === "JS" ? l.type : '未知插件',
      author: '@未知',
      describe: '暂无',
      pathname: l.name,
      pluginname: l.name,
      url: '未知'
    }
  }
  return a
}